import datetime
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic


class FavoriteManager(models.Manager):
    """
    A Manager for Favorite
    
    >>> User(username="alice").save()
    >>> User(username="bob").save()
    """
    def get_favorites_by_user(self, user):
        """
        This method returns favorite objects for a user
        
        this example below we set a favorite user for alice, which happens to be
        bob.  Then we can retrieve that favorite relation from the database
        
        >>> user = User.objects.get(username="alice")
        >>> fav_user = User.objects.get(username="bob")
        >>> fav1 = Favorite.create_favorite(user, fav_user)
        >>> Favorite.objects.get_favorites_by_user(user)
        [<Favorite: alice-bob>]
        """
        return self.filter(user=user)
    
    def get_favorites_by_model(self, model):
        """
        This method returns Favorite objects for any object of model that has 
        been selected as a favorite
        >>> user = User.objects.get(username="alice")
        >>> fav_user = User.objects.get(username="bob")
        >>> fav1 = Favorite.create_favorite(user, fav_user)
        >>> Favorite.objects.get_favorites_by_model(User)
        [<Favorite: alice-bob>]
        >>> Favorite.objects.all().delete()
        
        above if we get all the Favorite objects for users we see that alice's 
        favorite user is bob. 
        """
        ct = ContentType.objects.get_for_model(model)
        return self.filter(content_type = ct)

class Favorite(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.IntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    user = models.ForeignKey(User)
    date_added = models.DateTimeField(default=datetime.datetime.now)
    
    objects = FavoriteManager()
    
    def __unicode__(self):
        return "%s-%s" % (self.user, self.content_object)
    
    @classmethod
    def create_favorite(cls, user, content_object):
        """
        creates a favorite relation between user and content_object and saves it
        to the database.
        
        It returns the created Favorite object
        """
        ct = ContentType.objects.get_for_model(type(content_object))
        fav = cls(
            user=user, 
            content_type = ct, 
            object_id = content_object.id, 
            content_object = content_object
        )
        fav.save()
        return fav
        